from coffeetalk.protocol import ioelement
from coffeetalk.protocol.iotypes import defaulttype

class IOList(dict,defaulttype.DefaultType):
    
    _type = '[List]'
    require = ''
    __children = {}
    def __init__(self,name=None,require=''):
        defaulttype.DefaultType.__init__(self,name)
        
        self.require = require
        self.__children = {}
             
    def __getitem__(self,key):
        if self.__children.has_key(key):
            return self.__children[key]
        else:
            return dict.__getitem__(self,key)          
        
    def __setitem__(self,name,value):
        
        if hasattr(value,'_to_element'):
            if self.require != '':
                try:
                    checktype = ''
                    if hasattr(value,'_type'):
                        checktype = value._type
                    else:
                        checktype = str(value.__module__) + '.' + str(type(value).__name__)
                    if checktype == self.require:
                        self.__children[name] = value
                    else:
                        raise AttributeError('value must be of type %r, got %r instead' % (str(self.require),str(checktype)))
                except:
                    raise
            else:
                self.__children[name] = value
        else:
            raise AttributeError('%s %r must implement _to_element' % (name,value))
    
    def __len__(self):
        return len(self.__children)
    def __iter__(self):
        for key,value in self.__children.iteritems():
            yield key,value
    def __delitem__(self,k):
        del self.__children[k]
    def iterkeys(self):
        for key in self.__children.keys():
            yield key
    def itervalues(self):
        for value in self.__children.values():
            yield value
    def iteritems(self):
        for key,value in self.__children.iteritems():
            yield key,value
    def items(self):
        return [(k,v) for k,v in self.__children.iteritems()]
    def keys(self):
        return list(self.__children)
    def has_key(self,k):
        return self.__children.has_key(k)
    def __repr__(self):
        return str(self.__children)
    def __str__(self):
        return str(self._to_element())
    
    def _to_element(self):

        if self.require != '':
            returnelement = ioelement.IOElement(self.name,{'type':'[List]','require':self.require})
        else:
            returnelement = ioelement.IOElement(self.name,{})
        for value in self.__children.values():
            try:
                returnelement.add(value._to_element())
            except: 
                raise
            
        return returnelement
    
if __name__ == '__main__':
    import coffeetalk.protocol.iotypes as types
    l = IOList(name='Mike',require='[String]')
    print l
    l['New'] = types.String(name='New',value='Mike')
    print l
    
    m = l['New']
    
    print m
